package vn.edu.saigontech.ncms.web.study;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import flexjson.JSONSerializer;

import vn.edu.saigontech.ncms.model.enumeration.Currency;
import vn.edu.saigontech.ncms.model.info.Offering;
import vn.edu.saigontech.ncms.model.info.Receipt;
import vn.edu.saigontech.ncms.model.info.Student;
import vn.edu.saigontech.ncms.model.program.Level;
import vn.edu.saigontech.ncms.model.system.Money;
import vn.edu.saigontech.ncms.service.LevelService;
import vn.edu.saigontech.ncms.service.OfferingMemberService;
import vn.edu.saigontech.ncms.service.OfferingService;
import vn.edu.saigontech.ncms.service.ProgramService;
import vn.edu.saigontech.ncms.service.ReceiptService;
import vn.edu.saigontech.ncms.service.StudentService;
import vn.edu.saigontech.ncms.service.UserService;
import vn.edu.saigontech.ncms.util.DateUtil;
import vn.edu.saigontech.ncms.util.Checker;
import vn.edu.saigontech.ncms.vo.SelectOption;
import vn.edu.saigontech.ncms.web.BaseAction;

@SuppressWarnings("serial")
public class ReceiptAction extends BaseAction {
	
	private Long id;
	private Long levelId;
	private String number;
	private String date;
	private String fromDate;
	private String toDate;
	private Long offeringId;
	private String offeringName;
	private Long studentId;
	private String studentFirstName;
	private String studentLastName;
	private String studentDateOfBirth;
	private Double fee;
	private boolean active;
	private Long cashierId;
	private String comment;
	
	public String showAdd() {
		REQUEST().setAttribute("programs", ProgramService.INSTANCE.findAllAreActive());
		REQUEST().setAttribute("offering", OfferingService.INSTANCE.findById(this.offeringId));
		REQUEST().setAttribute("cashiers", UserService.INSTANCE.findByRole("Managing"));
		return SUCCESS;
	}
		
	public String add() {
		Student student = StudentService.INSTANCE.findById(studentId);
		Offering offering = OfferingService.INSTANCE.findById(offeringId);

		Receipt offeringReceipt = new Receipt();
		offeringReceipt.setNumber(number);
		offeringReceipt.setStudent(student);
		offeringReceipt.setOffering(offering);
		offeringReceipt.setDate(DateUtil.fromString(this.date, this.i18n("format.date")));
		offeringReceipt.setFee(new Money(this.fee, Currency.VND));
		offeringReceipt.setActive(true);
		offeringReceipt.setCashier(UserService.INSTANCE.findById(cashierId));
		offeringReceipt.setComment(comment);
		
		Receipt entity = ReceiptService.INSTANCE.persist(offeringReceipt);
		
		if(Checker.isNotNull(entity)) {
			this.addLoggingDetail(BaseAction.ADD, "logging.receipt.add", student.getFullName(), entity.getNumber(), offering.getName());
			OfferingMemberService.INSTANCE.add(entity.getId());
		}
		
		this.id = entity.getId();
		return SUCCESS;
	}
	
	public String info() {
		REQUEST().setAttribute("receipt", ReceiptService.INSTANCE.findById(this.id));
		return SUCCESS;
	}
	
	public String showEdit() {
//		REQUEST().setAttribute("programs", ProgramService.INSTANCE.findAllAreActive());
		Receipt receipt = ReceiptService.INSTANCE.findById(this.id);
		REQUEST().setAttribute("program", receipt.getOffering().getLevel().getProgram());
		REQUEST().setAttribute("receipt", receipt);
		REQUEST().setAttribute("cashiers", UserService.INSTANCE.findAllByRole("Consulting"));
		return SUCCESS;
	}
	
	public String edit() {
		Receipt receipt = ReceiptService.INSTANCE.findById(this.id);
		Offering offering = OfferingService.INSTANCE.findById(offeringId); 
		receipt.setOffering(offering);
		receipt.setNumber(this.number);
		receipt.setDate(DateUtil.fromString(this.date, this.i18n("format.date")));
		receipt.setFee(new Money(this.fee, Currency.VND));
		receipt.setCashier(UserService.INSTANCE.findById(cashierId));
		// both receipt and member will be disable
		receipt.setActive(active);
		//receipt.getOfferingMember().setActive(active);
		receipt.getMember().setActive(active);
		receipt.setComment(comment);
		
		Receipt entity = ReceiptService.INSTANCE.persist(receipt);

		if(Checker.isNotNull(entity)) {
			this.addLoggingDetail(BaseAction.EDIT, "logging.receipt.edit", entity.getStudent().getFullName(), entity.getNumber(), offering.getName());
		}
		
		return SUCCESS;
	}
	
	public String delete() {
		Receipt receipt = ReceiptService.INSTANCE.findById(this.id);
		String studentName = receipt.getStudent().getFullName();
		String number = receipt.getNumber();
		String offeringName = receipt.getOffering().getName();
		
		if(ReceiptService.INSTANCE.deleteById(this.id)) {
			this.addLoggingDetail(BaseAction.DELETE, "logging.receipt.delete", studentName, number, offeringName);
		}
		return SUCCESS;
	}
	
	public String showSearch() {
		REQUEST().setAttribute("cashiers", UserService.INSTANCE.findByRole("office"));
		return SUCCESS;
	}
	
	public String search() {
		Date birthday = Checker.isDate(this.studentDateOfBirth, this.i18n("format.date"))? DateUtil.fromString(this.studentDateOfBirth, this.i18n("format.date")) : null;
		Date date = Checker.isDate(this.date, this.i18n("format.date"))? DateUtil.fromString(this.date, this.i18n("format.date")) : null;
		Date fromDate = Checker.isDate(this.fromDate, this.i18n("format.date"))? DateUtil.fromString(this.fromDate, this.i18n("format.date")) : null;
		Date toDate = Checker.isDate(this.toDate, this.i18n("format.date"))? DateUtil.fromString(this.toDate, this.i18n("format.date")) : null;
		Money money = Checker.isNotNull(this.fee)? new Money(this.fee, Currency.VND) : null;
		
		Collection<Receipt> receipts = ReceiptService.INSTANCE.find(
				this.studentFirstName, this.studentLastName, birthday, 
				this.number, date, fromDate,DateUtil.endOfDate(toDate), this.offeringName,
				money, this.cashierId, this.comment
		);
		REQUEST().setAttribute("receipts", receipts);
		this.addLoggingDetail(BaseAction.SEARCH, "logging.receipt.search");
		return SUCCESS;
	}
	
	public String requestOfferingByLevelId() {
		Level level = LevelService.INSTANCE.findById(this.levelId);
		List<SelectOption> optionList = new ArrayList<SelectOption>();
		for(Offering offering : level.getOfferings()) {
			SelectOption selectOption = new SelectOption();
			selectOption.setValue(String.valueOf(offering.getId()));
			selectOption.setCaption(DateUtil.toString(offering.getStartDate(), this.i18n("format.date")) +  "-" +
					                DateUtil.toString(offering.getEndDate(), this.i18n("format.date")) + " # " +  
					                offering.getName());
			optionList.add(selectOption);
		}
		try {
			RESPONSE().getWriter().write(new JSONSerializer().serialize(optionList));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return NONE;
	}

	public Long getLevelId() {
		return levelId;
	}

	public void setLevelId(Long levelId) {
		this.levelId = levelId;
	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public String getNumber() {
		return number;
	}

	public void setNumber(String number) {
		this.number = number;
	}

	public String getDate() {
		return date;
	}

	public void setDate(String date) {
		this.date = date;
	}

	public Long getOfferingId() {
		return offeringId;
	}

	public void setOfferingId(Long offeringId) {
		this.offeringId = offeringId;
	}

	public String getOfferingName() {
		return offeringName;
	}

	public void setOfferingName(String offeringName) {
		this.offeringName = offeringName;
	}

	public Long getStudentId() {
		return studentId;
	}

	public void setStudentId(Long studentId) {
		this.studentId = studentId;
	}

	public String getStudentFirstName() {
		return studentFirstName;
	}

	public void setStudentFirstName(String studentFirstName) {
		this.studentFirstName = studentFirstName;
	}

	public String getStudentLastName() {
		return studentLastName;
	}

	public void setStudentLastName(String studentLastName) {
		this.studentLastName = studentLastName;
	}

	public String getStudentDateOfBirth() {
		return studentDateOfBirth;
	}

	public void setStudentDateOfBirth(String studentDateOfBirth) {
		this.studentDateOfBirth = studentDateOfBirth;
	}

	public Double getFee() {
		return fee;
	}

	public void setFee(Double fee) {
		this.fee = fee;
	}

	public boolean isActive() {
		return active;
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public Long getCashierId() {
		return cashierId;
	}

	public void setCashierId(Long cashierId) {
		this.cashierId = cashierId;
	}

	public String getComment() {
		return comment;
	}

	public void setComment(String comment) {
		this.comment = comment;
	}

	public String getToDate() {
		return toDate;
	}

	public void setToDate(String toDate) {
		this.toDate = toDate;
	}

	public String getFromDate() {
		return fromDate;
	}

	public void setFromDate(String fromDate) {
		this.fromDate = fromDate;
	}
}
